#include <jni.h>
#include <string>
#include <opencv2/opencv.hpp>
#include <android/log.h>
#define TAG "FACE_TAG"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
using namespace cv;
DetectionBasedTracker *tracker=0;
class CascadeDetectorAdapter: public DetectionBasedTracker::IDetector
{
public:
    CascadeDetectorAdapter(cv::Ptr<cv::CascadeClassifier> detector):
            IDetector(),
            Detector(detector)
    {
        CV_Assert(detector);
    }
//检测到人脸 调用 返回 Mat ==bitmap
    void detect(const cv::Mat &Image, std::vector<cv::Rect> &objects)
    {
        Detector->detectMultiScale(Image, objects, scaleFactor, minNeighbours, 0, minObjSize, maxObjSize);

    }

    virtual ~CascadeDetectorAdapter()
    {
    }
private:
    CascadeDetectorAdapter();
    cv::Ptr<cv::CascadeClassifier> Detector;
};


extern "C"
JNIEXPORT void JNICALL
Java_com_example_opencv_1find_1face_FaceDetection_loadCascade(JNIEnv *env, jobject instance,
                                                              jstring filePath_) {
    const char *filePath = env->GetStringUTFChars(filePath_, 0);
    //检测器
    //智能指针
    Ptr<CascadeClassifier> classifier=makePtr<CascadeClassifier>(filePath);
    //创建检测器
    Ptr<CascadeDetectorAdapter> mainDetector=makePtr<CascadeDetectorAdapter>(classifier);
    //------------------------------------------------------------
    //跟踪器
    //智能指针
    Ptr<CascadeClassifier> classifier1=makePtr<CascadeClassifier>(filePath);
    //创建检测器
    Ptr<CascadeDetectorAdapter> trackingDetector=makePtr<CascadeDetectorAdapter>(classifier1);
    DetectionBasedTracker::Parameters DetectorParams;
    //tracker 含两个对象 检测器  跟踪器
    tracker =new DetectionBasedTracker(mainDetector,trackingDetector,DetectorParams);
    tracker->run();

    LOGE("人脸识别级联分类器加载成功");
    env->ReleaseStringUTFChars(filePath_, filePath);
}
int i=0;
extern "C"
JNIEXPORT void JNICALL
Java_com_example_opencv_1find_1face_FaceDetection_faceDetection__JI(JNIEnv *env, jobject instance,
                                                                    jlong nativeObj,
                                                                    jint CameraId) {
    Mat *src = reinterpret_cast<Mat *>(nativeObj);
    if (CameraId==1){
        rotate(*src,*src,ROTATE_90_COUNTERCLOCKWISE );
        flip(*src,*src,1);
    } else{
        rotate(*src,*src,ROTATE_90_CLOCKWISE);
    }
    Mat grayMat;
    // 2. 转成灰度图，提升运算速度，灰度图所对应的 CV_8UC1 单颜色通道，信息量少 0-255 1u
    cvtColor(*src, grayMat, COLOR_BGRA2GRAY);
    // 4. 检测人脸，这是个大问题
    // 参数 1.1 会采取上采样和降采样 ，缩放比例
    // 参数 3 检测多少次
    // 参数 Size(width / 2, height / 2) 最小脸的大小
    //增强对比度  黑白 轮廓（二值化处理）
    std::vector<Rect> faces;
    equalizeHist(grayMat,grayMat);
    tracker->process(grayMat);
    tracker->getObjects(faces);

    LOGE("人脸size = %d", faces.size());
    if (faces.size() == 0) {
        return;
    }
    //存放人脸的Mat矩阵
    Mat faceMat;
   //存放彩色原图Mat矩阵
    Mat src1;
    cvtColor(*src, src1, COLOR_BGRA2RGB);
    for(Rect face:faces){
        rectangle(*src,face,Scalar(255,0,0,255), 4, LINE_AA);
        //复制出含有人像部分像素矩阵
        grayMat(face).copyTo(faceMat);
                char p[100];
               sprintf(p,"/storage/emulated/0/Ling/%d.jpg",i++);
               //人脸部分图像，存入sd卡中
               imwrite(p,faceMat);
    }
   // src1.release();
    faceMat.release();
    grayMat.release();
}

